; include the following in your file (without commentsign (';')) before you
; include this file
; select what type of outputfile you want with setting FALSE to TRUE
; settype outputfile utility    is needed for UTILITY
; settype outputfile module     is needed for SIMPLE_MODULE and MODULE

;ABSOLUTE      .EQU FALSE
;AOF           .EQU FALSE
;UTILITY       .EQU FALSE
;SIMPLE_MODULE .EQU FALSE
;MODULE        .EQU FALSE

; if you set AOF to TRUE, you need the information for the current name
; of the procedure (in AOF-files you may need more then one procedures cause 
; of linking multiple AOF-files)
; include the following in your file (without commentsign (';')) before you
; include this file (include the macro and not the .PROC command)
; and change the term "select_a_name_of_procedure" if neccessary

; .MACRO select_a_procedurename 
;  .PROC select_a_name_of_procedure
; .ENDM 

; if you set SIMPLE_MODULE to TRUE ( result is a module with 1 entry via
; commandline with the Command_keyword) you need to define the following
; adresses somewhere behind you include this file ( jump over this strings
; or place it after the SWI XOS_Exit

;Title_string       (adress of a string of module title)
;Help_string        (adress of a string with text of help command)
;Command_keyword    (adress of a string with Command_keyword to start program)

; if you set MODULE to TRUE, you need the information for the module-header
; if a feature should not be available use the .EQU 0 command else use the
; name as adress
; include the following in your file (without commentsign (';')) before you
; include this file
;***************************************************************************
; WARNING: in modules there may be a direct jump to a adress
; Check that no formula-command is invoked without the initialision with the
; macro
;formulainit
;***************************************************************************

;Start_code                     .EQU 0
;Initialisation_code            .EQU 0
;Finalisation_code              .EQU 0
;Service_call_handler           .EQU 0
;Title_string                   .EQU 0
;Help_string                    .EQU 0
;Help_and_command_keyword_table .EQU 0
;SWI_chunk_base_number          .EQU 0
;SWI_handler_code               .EQU 0
;SWI_decoding_table             .EQU 0
;SWI_decoding_code              .EQU 0

 .INCLUDE <formula_tlaconfig$dir>.tlaconfig 

; used macros following

 .MACRO LADR
\adress
  .IF \adress- %2 >65524.
   MOV %1,#((\adress - %2 + 8 + 12.) & 0FF)
   ADD %1,%1,#(((\adress - %2 + 8 + 12.) / 100) &0FF) << 8   
   ADD %1,%1,#((\adress - %2 + 8 + 12.) / 10000) << 16.  
  .ELSE
   MOV %1,#((\adress - %2 + 8 + 8) & 0FF)
   ADD %1,%1,#(((\adress - %2 + 8 + 8) / 100) &0FF) << 8 
  .ENDC  
  SUB %1,PC,%1
 .ENDM

 .MACRO	ADDR
\addr
  .IF \addr- %2 >255.
   LADR %1,%2
  .ELSE
   ADR %1,%2
  .ENDC
 .ENDM

 .MACRO	LD
\load 
  .IF \load- %2 >4084.
   LADR %1,%2
   LDR %1,[%1]
  .ELSE
   LDR %1,%2
  .ENDC
 .ENDM

 .MACRO	LDB
\load 
  .IF \load- %2 >4084.
   LADR %1,%2
   LDRB %1,[%1]
  .ELSE
   LDRB %1,%2
  .ENDC
 .ENDM

 .MACRO	ST
\store
  .IF \store- %2 >4084.
   LADR tempregister,%2
   STR %1,[tempregister]
  .ELSE
   STR %1,%2
  .ENDC
 .ENDM

 .MACRO	STB
\store
  .IF \store- %2 >4084.
   LADR tempregister,%2
   STRB %1,[tempregister]
  .ELSE
   STRB %1,%2
  .ENDC
 .ENDM

 .MACRO BACKADDR
  LDR tempregister,\goadress
  ADD %1,PC,tempregister
  B \ready 
\goadress .WORD %2-\goadress
\ready
 .ENDM
  
 
 .MACRO formuladata
; stackspace for the stack of formula 
; Invoke this only one time !!!! 

 B formulajump  
formulatemp         .BLOCK formulastacklength,0 
 .ALIGN
formularegistersave .BLOCK 64.   
 .ALIGN
formulaclitail      .BLOCK 257.,0
 .ALIGN
formulamystackregistersave    .WORD  0
formulajump 
 
formula_one .EQU 1
 .ENDM

; initialisation for formula, MUST be called before the first formulacommand 
; change values of stackregister and tempregister  

 .MACRO formulainit
  .IF MODULE | SIMPLE_MODULE | UTILITY
   formulamoduleinit
  .ENDC
  LADR stackregister,formulatemp
  LADR tempregister,formulamystackregistersave
  STR  stackregister,[tempregister]
  STR  stackregister,[stackregister,#4]
  .IF MODULE | SIMPLE_MODULE | UTILITY
   .IF formulatempregistersave  | formulastackregistersave
    ADDR R0,formularegistersave
    LDR R12,[R0,#(12*4)]
    LDR R11,[R0,#(11*4)]
    LDR R0,[R0,#(0*4)]
   .ENDC
  .ENDC
 .ENDM

 .MACRO formulamoduleinit
  ; save all Registers (you may need some of them in modules)
  STR R0,\R0save
  STR R11,\R11save
  ADDR R0,formularegistersave
  STR R1 ,[R0,#(1.*4)]
  STR R2 ,[R0,#(2.*4)]
  STR R3 ,[R0,#(3.*4)]
  STR R4 ,[R0,#(4.*4)]
  STR R5 ,[R0,#(5.*4)]
  STR R6 ,[R0,#(6.*4)]
  STR R7 ,[R0,#(7.*4)]
  STR R8 ,[R0,#(8.*4)]
  STR R9 ,[R0,#(9.*4)]
  STR R10,[R0,#(10.*4)]
 
  STR R12,[R0,#(12.*4)]
  STR R13,[R0,#(13.*4)]
  STR R14,[R0,#(14.*4)]
  STR R15,[R0,#(15.*4)]
  LDR R2,\R0save
  STR R2 ,[R0,#(0.*4)]         
  LDR R2,\R11save
  STR R2 ,[R0,#(11.*4)]         
  LDR R0,\R0save
   
  .IF MODULE | SIMPLE_MODULE 
   ; Terminate Commandline-tail with 0 (currently terminated with 13.)
   ADDR R6,formulaclitail
   MOV R5,R6
   CMP R0,#0
   BEQ \ready
   MOV R2,#0 
\copy
    ADD R3,R0,R2
    ADD R5,R6,R2
    MOV R4,#0
    LDRB R4,[R3]
    STRB R4,[R5]
    CMP   R4,#32.
    BLT \ready 
    CMP R2,#0FF
    BEQ \ready
    ADD R2,R2,#1
    B \copy
\ready
   MOV R4,#0
   STRB R4,[R5]
   ADDR R0,formularegistersave
;   LDR R1 ,[R0,#(1.*4)]
   LDR R2 ,[R0,#(2.*4)]
   LDR R3 ,[R0,#(3.*4)]
   LDR R4 ,[R0,#(4.*4)]
   LDR R5 ,[R0,#(5.*4)]
   LDR R6 ,[R0,#(6.*4)]
;   LDR R7 ,[R0,#(7.*4)]
;   LDR R8 ,[R0,#(8.*4)]
;   LDR R9 ,[R0,#(9.*4)]
;   LDR R10,[R0,#(10.*4)]
 
;   LDR R12,[R0,#(12.*4)]
;   LDR R13,[R0,#(13.*4)]
;   LDR R14,[R0,#(14.*4)]
   LDR R0,\R0save
   LDR R11,\R11save
  .ENDC
  B \hupf
\R0save .WORD 0
\R11save .WORD 0
\hupf
 .ENDM

 .MACRO progdef
  .IF AOF
   select_a_procedurename 
  .ELSE  
   .PROC formula
  .ENDC
 .ENDM

 .IF ABSOLUTE 
  .IF AOF
   .ERROR select either AOF .EQU TRUE or ABSOLUTE .EQU TRUE not both !
   .END
  .ELSE 
   .IF UTILITY
    .ERROR select either UTILITY .EQU TRUE or ABSOLUTE .EQU TRUE not both !
    .END
   .ELSE
    .IF MODULE
     .ERROR select either MODULE .EQU TRUE or ABSOLUTE .EQU TRUE not both !
     .END
    .ELSE
     .IF SIMPLE_MODULE
      .ERROR select either SIMPLE_MODULE .EQU TRUE or ABSOLUTE .EQU TRUE not both !
      .END
     .ELSE
;absolute start-code
      .ABSOLUTE
      progdef      
      formuladata
      formulainit
     .ENDC
    .ENDC
   .ENDC
  .ENDC
 .ELSE
  .IF AOF
   .IF UTILITY
    .ERROR select either UTILITY .EQU TRUE or AOF .EQU TRUE not both !
   .END
   .ELSE
    .IF MODULE
     .ERROR select either MODULE .EQU TRUE or AOF .EQU TRUE not both !
     .END
    .ELSE
     .IF SIMPLE_MODULE
      .ERROR select either SIMPLE_MODULE .EQU TRUE or AOF .EQU TRUE not both !
      .END
     .ELSE
;aof start-code
      progdef
      formuladata
      formulainit
     .ENDC
    .ENDC
   .ENDC
  .ELSE
   .IF UTILITY
    .IF MODULE 
     .ERROR select either UTILITY .EQU TRUE or MODULE .EQU TRUE not both !
     .END
    .ELSE
     .IF SIMPLE_MODULE 
      .ERROR select either UTILITY .EQU TRUE or SIMPLE_MODULE .EQU TRUE not both !
      .END
     .ELSE
;utility start-code
      .ABSOLUTE
      progdef
      .ORG 0000  
      formuladata
      formulainit 
     .ENDC  
    .ENDC
   .ELSE
    .IF MODULE
     .IF SIMPLE_MODULE 
      .ERROR select either MODULE .EQU TRUE or SIMPLE_MODULE .EQU TRUE not both !
      .END
     .ELSE
;module start-code
      .ABSOLUTE
      progdef
      .ORG 0000
      .WORD Start_code
      .WORD Initialisation_code
      .WORD Finalisation_code
      .WORD Service_call_handler
      .WORD Title_string
      .WORD Help_string
      .WORD Help_and_command_keyword_table
      .WORD SWI_chunk_base_number
      .WORD SWI_handler_code
      .WORD SWI_decoding_table
      .WORD SWI_decoding_code
      formuladata
     .ENDC
    .ELSE
     .IF SIMPLE_MODULE
;simple module start-code
      .ABSOLUTE
      progdef
      .ORG 0000
      .WORD 0
      .WORD Initialisation_code
      .WORD 0
      .WORD 0
      .WORD Title_string
      .WORD Title_string
      .WORD Help_and_command_keyword_table
      .WORD 0
      .WORD 0
      .WORD 0
      .WORD 0
Help_and_command_keyword_table
      .BLOCK Command_keyword_length,32.
      .BYTE 0
      .ALIGN 
      .WORD formulastart
      .BYTE 0
      .BYTE 0
      .BYTE 255.
      .BYTE 0
      .WORD 0
      .WORD Help_string   
      .WORD 0
Initialisation_code
      BACKADDR R1,Command_keyword
      ADR R2,Help_and_command_keyword_table
      MOV R3,#Command_keyword_length
\loop
       LDRB R4,[R1]
       CMP  R4,#0
       BEQ \end
        CMP R3,#0
        BEQ \end
        STRB R4,[R2]
        ADD  R1,R1,#1
        ADD  R2,R2,#1
        SUB  R3,R3,#1
        B \loop
\end  
      MOV PC,R14
      MOV R0,R0
      formuladata
formulastart
      formulainit
     .ELSE
      .ERROR select either UTILITY .EQU TRUE or MODULE .EQU TRUE or ABSOLUTE .EQU TRUE or AOF .EQU TRUE or SIMPLE_MODULE .EQU TRUE     
      .ERROR and use for the rest .EQU FALSE  
      .END
     .ENDC
    .ENDC
   .ENDC
  .ENDC  
 .ENDC

 .INCLUDE <formula_go$dir>.go

 .MACRO saveregister
  .IF formulastackregistersave
   .IF formulatempregistersave
    STR tempregister,\tempregistersave
   .ENDC
   LD  tempregister,formulamystackregistersave
   STR stackregister,[tempregister,#4]
   MOV stackregister,tempregister
  .ENDC
  .IF formulaflagsave
   MOV tempregister,R15
   AND tempregister,tempregister,#0FC << 24.
   STR tempregister,[stackregister,#8]
  .ENDC
  .IF formulatempregistersave 
   .IF formulastackregistersave
    LDR tempregister,\tempregistersave
    GO \hupf
\tempregistersave .WORD 0 
\hupf
   .ENDC
   STR tempregister,[stackregister,#0]
  .ENDC
 .ENDM 

 .MACRO restoreregister
  .IF formulaflagsave
   LDR tempregister,[stackregister,#8]
   TEQP R15,#0FC << 24. 
   TEQP R15,tempregister 
  .ENDC
  .IF formulatempregistersave
   LDR tempregister,[stackregister,#0]
  .ENDC
  .IF formulastackregistersave
   LDR stackregister,[stackregister,#4]
  .ENDC
 .ENDM 

 .MACRO STACKadd
  INTsum %1,%2,#%3
  .IF formulastackregistersave
   ST stackregister,formulamystackregistersave
  .ENDC  
 .ENDM

 .MACRO STACKsub
  INTsubtract %1,%2,#%3
  .IF formulastackregistersave
   ST stackregister,formulamystackregistersave
  .ENDC  
 .ENDM

 .MACRO callprocedure
\selfadress
  ADR R11,\selfadress
  MOV R11,R11  
  STR R11,[R12,#12.]
  B formulalabel%1
  .IF R0<>%2
   MOV %2,R0
  .ENDC 
 .ENDM

 .MACRO returnprocedure
  LDR R15,[R12,#12.]
  MOV R0,R0
 .ENDM

; malloc/free not really implementated (not sure, what method is the best ...)
   
 .MACRO formula_malloc
  GO \hupf
\nix1 .BLOCK %2,0
 .ALIGN
\hupf
  ADR tempregister,\nix1  
  STR tempregister,[stackregister,#%1]
 .ENDM  

 .MACRO DEFSTORE
%1 .BLOCK %2,%3
  .ALIGN
 .ENDM 

 .IF SHORT 
  .IF MUFTI
   .ERROR select either MUFTI .EQU TRUE or SHORT .EQU TRUE not both !
   .END
  .ELSE 
   .IF HUGHES
    .ERROR select either HUGHES .EQU TRUE or SHORT .EQU TRUE not both !
    .END
   .ELSE
    .IF WILLIAMS
     .ERROR select either WILLIAMS .EQU TRUE or SHORT .EQU TRUE not both !
     .END
    .ELSE
;SHORT 
     .INCLUDE <formula$dir>.intdiv.short
    .ENDC
   .ENDC
  .ENDC
 .ELSE
  .IF MUFTI
   .IF HUGHES
    .ERROR select either HUGHES .EQU TRUE or MUFTI .EQU TRUE not both !
   .END
   .ELSE
    .IF WILLIAMS
     .ERROR select either WILLIAMS .EQU TRUE or MUFTI .EQU TRUE not both !
     .END
    .ELSE
;MUFTI 
     .INCLUDE <formula$dir>.intdiv.mufti      
    .ENDC
   .ENDC
  .ELSE
   .IF HUGHES
    .IF WILLIAMS 
     .ERROR select either HUGHES .EQU TRUE or WILLIAMS .EQU TRUE not both !
     .END
    .ELSE
;HUGHES start-code
     .INCLUDE <formula$dir>.intdiv.hughes    
    .ENDC
   .ELSE
    .IF WILLIAMS
;WILLIAMS start-code
     .INCLUDE <formula$dir>.intdiv.williams
    .ELSE
     .ERROR select either HUGHES .EQU TRUE or WILLIAMS .EQU TRUE or SHORT .EQU TRUE or MUFTI .EQU TRUE      
     .ERROR and use for the rest .EQU FALSE  
     .END
    .ENDC
   .ENDC
  .ENDC  
 .ENDC

 .MACRO makechar 
  MOV tempregister,#0FF
  AND %1,%1,tempregister
  CMP %1,#7F
  MVNGT tempregister,tempregister
  ORRGT %1,%1,tempregister 
 .ENDM

 .MACRO INTconstlongload
  LDR %1,\temp
  GO \jump2
\temp .WORD %2
\jump2 
 .ENDM

 .MACRO INTconstload 
  .IF 100<%2
    INTconstlongload %1,%2
  .ELSE
   .IF 0>%2
    INTconstlongload %1,%2
   .ELSE
    MOV %1,#%2
   .ENDC
  .ENDC
 .ENDM
  
 .MACRO INTsum
  ADD %1,%2,%3
 .ENDM
 
 .MACRO INTsubtract
  SUB %1,%2,%3
 .ENDM
 
 .MACRO INTmultiply
  .IF %1=%2 
   .IF %1=%3
     MOV tempregister,%2
     MUL %1,tempregister,%3
   .ELSE
     MUL %1,%3,%2
   .ENDC
  .ELSE
   MUL %1,%2,%3
  .ENDC 
 .ENDM

 .MACRO INTconstmult
  .IF %2<>1 
   .IF %2=4
    MOV %1,%1,ASL #2  
   .ELSE
    INTconstload tempregister,%2
    MUL %1,tempregister,%1
   .ENDC
  .ENDC 
 .ENDM


 .MACRO INTdivide
  INTdivide_mac %1,%2,%3
 .ENDM

 .MACRO INTmodulo
  STR %2,\temp2
  STR %3,\temp3
  INTdivide_mac %1,%2,%3
  MOV tempregister,%1
  LDR %2,\temp2
  LDR %3,\temp3
  MUL tempregister,%3,tempregister
  SUB %1,%2,tempregister
  B \ready
\temp2 .WORD 0
\temp3 .WORD 0
\ready
 .ENDM
  
 .MACRO INTshiftleft
  MOV %1,%2,LSL %3
 .ENDM 

 .MACRO INTshiftright
  MOV %1,%2,LSR %3
 .ENDM 

 .MACRO INTbitand
  AND %1,%2,%3
 .ENDM

 .MACRO INTbiteor
  EOR %1,%2,%3
 .ENDM

 .MACRO INTbitor
  ORR %1,%2,%3
 .ENDM

 .MACRO INTbitinvert
  MVN %1,%2
 .ENDM

 .MACRO INTnegate
  RSB %1,%2,#0
 .ENDM
 
 .MACRO INTvarstore
  ST %2,%1
 .ENDM

 .MACRO INTvarload
  LD %1,%2
 .ENDM

 .MACRO INTadressload
  .IF %1<>%2
   MOV %1,%2
  .ENDC
 .ENDM

 .MACRO INToperandconstantadressload
  ADDR %1,%2
 .ENDM

 .MACRO INToperandvariableadressload
  ADDR %1,%2
 .ENDM

 .MACRO INToperandstackadressload
  INTconstload tempregister,%2
  ADD %1,stackregister,tempregister
 .ENDM

 .MACRO INToperandregisteradressload
  MOV %1,%2
 .ENDM
 
 .MACRO INTregstore
  .IF %1<>%2
   MOV %1,%2
  .ENDC
 .ENDM

 .MACRO INTregload
  .IF %1<>%2
   MOV %1,%2
  .ENDC
 .ENDM

 .MACRO INTstoretoadress
  STR %2,[%1]
 .ENDM

 .MACRO INTloadfromadress
  LDR %1,[%2]
 .ENDM

 .MACRO INTcontence
  LDR %1,[%2]
 .ENDM
  
 .MACRO INTnot
  CMP %2,#0
  MOVEQ %1,#1
  MOVNE %1,#0 
 .ENDM
 
 .MACRO INTequal 
  CMP %2,%3
  MOVEQ %1,#1
  MOVNE %1,#0
 .ENDM
 
 .MACRO INTnotequal
  CMP %2,%3
  MOVNE %1,#1
  MOVEQ %1,#0
 .ENDM
 
 .MACRO INTgreaterequal
  CMP %2,%3
  MOVGE %1,#1
  MOVLT %1,#0
 .ENDM
 
 .MACRO INTlessequal 
  CMP %2,%3
  MOVLE %1,#1
  MOVGT %1,#0
 .ENDM
 
 .MACRO INTgreater 
  CMP %2,%3
  MOVGT %1,#1
  MOVLE %1,#0
 .ENDM
 
 .MACRO INTless 
  CMP %2,%3
  MOVLT %1,#1
  MOVGE %1,#0
 .ENDM
 
 .MACRO INTor 
  ORR %1,%2,%3
 .ENDM
 
 .MACRO INTand 
  AND %1,%2,%3
 .ENDM
 
 .MACRO INTstackload 
  LDR %1,[stackregister,#%2]
 .ENDM

 .MACRO INTstackstore 
  STR %2,[stackregister,#%1]
 .ENDM

 .MACRO CHARnegate
  INTnegate %1,%2 
 .ENDM
 
 .MACRO CHARsum
  INTsum %1,%2,%3
 .ENDM
 
 .MACRO CHARsubtract
  INTsubtract %1,%2,%3
 .ENDM
 
 .MACRO CHARshiftleft
  INTshiftleft %1,%2,%3
 .ENDM 

 .MACRO CHARshiftright
  INTshiftright %1,%2,%3
 .ENDM 

 .MACRO CHARbitand
  INTbitand %1,%2,%3
 .ENDM

 .MACRO CHARbiteor
  INTbiteor %1,%2,%3
 .ENDM

 .MACRO CHARbitor
  INTbitor %1,%2,%3
 .ENDM

 .MACRO CHARbitinvert
  INTbitinvert %1,%2
 .ENDM

 .MACRO CHARequal 
  INTequal %1,%2,%3
 .ENDM
 
 .MACRO CHARnotequal
  INTnotequal %1,%2,%3
 .ENDM
 
 .MACRO CHARgreaterequal
  INTgreaterequal %1,%2,%3
 .ENDM
 
 .MACRO CHARlessequal 
  INTlessequal %1,%2,%3
 .ENDM
 
 .MACRO CHARgreater
  INTgreater %1,%2,%3 
 .ENDM
 
 .MACRO CHARless
  INTless %1,%2,%3 
 .ENDM
 
 .MACRO CHARconstload
  MOV %1,#%2
 .ENDM

 .MACRO CHARvarload
  LDB %1,%2
 .ENDM
 
 .MACRO CHARvarstore
  STB %2,%1
 .ENDM

 .MACRO CHARregstore
  .IF %1<>%2
   MOV %1,%2
  .ENDC
 .ENDM
 
 .MACRO CHARstoretoadress
  STRB %2,[%1]
 .ENDM

 .MACRO CHARloadfromadress
  LDRB %1,[%2]
 .ENDM

 .MACRO CHARcontence
  LDRB %1,[%2]
 .ENDM
  
 .MACRO CHARstackload 
  LDRB %1,[stackregister,#%2]
 .ENDM

 .MACRO CHARstackstore 
  STRB %2,[stackregister,#%1]
 .ENDM  

 .MACRO STRINGconstload 
  GO \hupf
\adress .STRING %2
 .ALIGN
 .WORD 0
\hupf
  ADR %1,\adress
 .ENDM
  
 .MACRO CHARtostring
  MOV tempregister,#%3
  STRB tempregister,[%1,#%2]
 .ENDM
  

 .MACRO INTPTRconstload
  ADDR %1,%2
 .ENDM

 .MACRO INTPTRsum
  INTsum %1,%2,%3
 .ENDM

 .MACRO INTPTRsubtract
  INTsubtract %1,%2,%3
 .ENDM
 
 .MACRO INTPTRvarload 
  INTvarload %1,%2
 .ENDM

 .MACRO INTPTRadressload
  .IF %1<>%2
   MOV %1,%2
  .ENDC
 .ENDM

 .MACRO INTPTRstackload 
  LDR %1,[stackregister,#%2]
 .ENDM

 .MACRO INTPTRstackstore 
  STR %2,[stackregister,#%1]
 .ENDM

 .MACRO INTPTRcontence
  INTcontence %1,%2
 .ENDM

 .MACRO INTPTRvarstore
  ST %2,%1
 .ENDM

 .MACRO INTPTRstoretoadress
  STR %2,[%1]
 .ENDM
  
 .MACRO INTPTRloadfromadress
  LDR %1,[%2]
 .ENDM

 .MACRO INTPTRstoretoadressptr
  STR %2,[%1]
 .ENDM
  
 .MACRO INTPTRloadfromadressptr
  LDR %1,[%2]
 .ENDM

 .MACRO INTPTRstructload
  ADD %1,%2,%3
 .ENDM

 .MACRO CHARPTRconstload
  INTPTRconstload %1,%2
 .ENDM

 .MACRO CHARPTRvarload 
  INTvarload %1,%2
 .ENDM

 .MACRO CHARPTRvarstore
  ST %2,%1
 .ENDM

 .MACRO CHARPTRstackload 
  LDR %1,[stackregister,#%2]
 .ENDM

 .MACRO CHARPTRstackstore 
  STR %2,[stackregister,#%1]
 .ENDM  

 .MACRO CHARPTRcontence
  CHARcontence %1,%2
 .ENDM

 .MACRO CHARPTRstoretoadress
  STRB %2,[%1]
 .ENDM

 .MACRO CHARPTRloadfromadress
  LDRB %1,[%2]
 .ENDM

 .MACRO CHARPTRstoretoadressptr
  STR %2,[%1]
 .ENDM

 .MACRO CHARPTRloadfromadressptr
  LDR %1,[%2]
 .ENDM

 .MACRO STRUCTvarload
  ADDR %1,%2
 .ENDM

 .MACRO STRUCTPTRvarload
  LD %1,%2
 .ENDM

 .MACRO STRUCTvarstore
  ST %2,%1
 .ENDM

 .MACRO STRUCTPTRvarstore
  ST %2,%1
 .ENDM

 .MACRO STRUCTstackload
  LDR %1,[stackregister,#%2]
 .ENDM

 .MACRO STRUCTstackstore
  STR %2,[stackregister,#%1]
 .ENDM

 .MACRO STRUCTPTRstackload
  LDR %1,[stackregister,#%2]
 .ENDM

 .MACRO STRUCTPTRstackstore
  STR %2,[stackregister,#%1]
 .ENDM

 .MACRO STRUCTPTRadressload
  .IF %1<>%2
   MOV %1,%2
  .ENDC
 .ENDM

 .MACRO STRUCTPTRindirectload
  LDR R11,[%2]
  ADD %1,%3,R11
 .ENDM

 .MACRO STRUCTPTRstructload
  ADD %1,%2,%3
 .ENDM

 .MACRO STRUCTPTRstructptrload
  LDR %1,[%1]
  ADD %1,%2,%3
 .ENDM

 .MACRO STRUCTPTRloadfromadress
  LDR %1,[%2]
 .ENDM

 .MACRO STRUCTPTRloadfromadressptr
  LDR %1,[%2]
 .ENDM

 .MACRO STRUCTPTRstoretoadress
  STR %2,[%1]
 .ENDM

 .MACRO STRUCTPTRstoretoadressptr
  STR %2,[%1]
 .ENDM

 .MACRO CHAR2INT
  MOV %1,%2
  MOV tempregister,#0FF
  MVN tempregister,tempregister  
  CMP %1,#7F
  ORRGT %1,%1,tempregister
 .ENDM
 
 .MACRO INT2CHAR
  MOV %1,%2
  makechar %1
 .ENDM
 
 .MACRO CHARPTR2CHAR
  MOV tempregister,%2
  MOV %1,#0
  LDRB %1,[tempregister]
  makechar %1   
 .ENDM

 .MACRO ifnotgoto 
  CMP %2,#0
  GOcond EQ,%1
 .ENDM
 
 .MACRO ifgoto 
  CMP %2,#0
  GOcond NE,%1
 .ENDM
  
 .MACRO goto
  GO %1
 .ENDM

 .ALIGN
 
